#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
    bayes服务器模块部分，用于处理与前端交互部分。
"""

import socket
import jieba
from concurrent.futures import ThreadPoolExecutor, wait
from server.bayes_dao import BayesDao


class BayesServer:
    def __init__(self, server_address, server_port, mysql_config):
        """
        构造函数。
        :param server_address:服务器ip地址
        :param server_port:服务器监听端口号
        :param mysql_config:mysql配置信息，字典(dict)类型
        """
        self.server_address = server_address
        self.server_port = server_port
        self.bayes_dao = BayesDao(mysql_config)

    def __server_thread(self, conn, address):
        """
        服务处理函数，用于处理一个连接。
        这个连接用于获得一封邮件，并处理这封邮件
        1、接收到用户传来的邮件长度问好
        2、发送Ready，通知客户端发送邮件
        3、接收邮件
        4、切割邮件，查询数据库参数，计算并判断是否为垃圾邮件，返回给客户端
        :param conn:服务器获取的连接对象
        :param address:连接客户端的ip地址
        :return:(True/False)
        """
        percent_spam_mul = 1
        percent_ham_mul = 1
        percent_spam_ber = 1
        percent_ham_ber = 1
        print('收到来自'+str(address)+'的请求：')
        msg = conn.recv(1024)
        email_length = msg.decode('utf-8')
        try:
            email_length = int(email_length)
        except Exception as err:
            print('来自'+address+'请求有误：'+str(err))
            conn.send('Error!'.encode('utf-8'))
            conn.close()
            return False
        conn.send('Ready'.encode('utf-8'))
        print('正在接收来自' + str(address) + '的邮件(' + str(email_length) + 'bytes)')
        email_content = conn.recv(email_length).decode('utf-8')
        words_list = list(jieba.cut(email_content))
        status = self.bayes_dao.select_email_words(words_list)
        if not status[0]:
            conn.send(('Server Error:'+status[1]).encode('utf-8'))
        elif status[0]:
            data = status[1]
            for percent in data["mul_spam_percent"]:
                percent_spam_mul = percent_spam_mul*percent
            percent_spam_mul = percent_spam_mul*data["mul_spam_all"]

            for percent in data["mul_ham_percent"]:
                percent_ham_mul = percent_ham_mul*percent
            percent_ham_mul = percent_ham_mul*data["mul_ham_all"]

            for percent in data["ber_spam_percent"]:
                percent_spam_ber = percent_spam_ber*percent
            percent_spam_ber = percent_spam_ber*data["ber_spam_all"]

            for percent in data["ber_ham_percent"]:
                percent_ham_ber = percent_ham_ber*percent
            percent_ham_ber = percent_ham_ber*data["ber_ham_all"]

            if percent_spam_ber > percent_ham_ber and \
                    percent_spam_mul > percent_ham_mul:
                conn.send('spam'.encode("utf-8"))
            else:
                conn.send('ham'.encode("utf-8"))
            conn.close()

    def start_server(self):
        """
        服务器启动方法,创建服务器。获取连接后，创建线程池进行处理。
        :return: 无
        """
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((self.server_address, self.server_port))
        server.listen(1)
        print('启动成功！')
        print('开始监听' + self.server_address + ':' + str(self.server_port) + '...')
        server_thread_pool = ThreadPoolExecutor(max_workers=10)
        future_list = []
        while True:
            conn, address = server.accept()
            future = server_thread_pool.submit(self.__server_thread,
                                               (conn, address))
            future_list.append(future)
        wait(future_list)
